package com.hi.hiparty.ui.fragment;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.hi.hiparty.R;
import com.hi.hiparty.service.ILocationService;
import com.hi.hiparty.util.StringUtils;

public class LocationInputFragment extends SherlockFragment implements TextWatcher {

	private static final String LOG_TAG = "LocationInputFragment";
	public static final String LOCATION_INPUT_FRAGMENT_TAG = "LocationInputFragment";

	private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
	private static final String TYPE_SEARCH = "/search";
	private static final String OUT_JSON = "/json";
	private static final String API_KEY = "AIzaSyDacZvdzTvCxW0wY9z_ghdf8TrUJXxT1-w";

	private SearchLocationAsyncTask searchTask;

	private ListView mListView;

	private EditText mLocationText;

	private OnItemClickListener onItemClickListener;

	private ILocationService locationService;

	public void setLocationService(ILocationService locationService) {
		this.locationService = locationService;
	}

	public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
		this.onItemClickListener = onItemClickListener;
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.location_input_search, container, false);
		mLocationText = (EditText) v.findViewById(R.id.location_input);
		mLocationText.addTextChangedListener(this);
		mListView = (ListView) v.findViewById(android.R.id.list);
		mListView.setOnItemClickListener(onItemClickListener);

		setHasOptionsMenu(true);
		return v;
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		getSherlockActivity().getSupportActionBar().setTitle(getString(R.string.ab_title_pub_new_party));
		getSherlockActivity().getSupportActionBar().setDisplayHomeAsUpEnabled(true);
		getSherlockActivity().getSupportActionBar().setHomeButtonEnabled(true);
	}

	@Override
	public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			getSherlockActivity().getSupportFragmentManager().popBackStack();
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	public void afterTextChanged(Editable s) {
		// TODO Auto-generated method stub

	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		queryLocation(this.mLocationText.getText().toString().trim());
	}

	private void queryLocation(String location) {
		if (StringUtils.isBlank(location))
			return;
		if (searchTask == null) {
			searchTask = new SearchLocationAsyncTask();
			searchTask.execute(location);
		} else {
			if (!location.equals(searchTask.searchLocation)) {
				searchTask.cancel(true);
				searchTask = new SearchLocationAsyncTask();
				searchTask.execute(location);
			}
		}
	}

	class SearchLocationAsyncTask extends AsyncTask<String, Void, List<JSONObject>> {

		public String searchLocation;

		@Override
		protected void onPostExecute(List<JSONObject> result) {
			super.onPostExecute(result);
			if (null != result) {
				List<Map<String, String>> locs = new ArrayList<Map<String, String>>();
				for (int i = 0; i < result.size(); i++) {
					try {
						Map<String, String> locMap = new HashMap<String, String>();
						locMap.put("name", result.get(i).getString("name"));
						JSONObject locJSON = result.get(i).getJSONObject("geometry").getJSONObject("location");
						locMap.put("latlng", locJSON.getDouble("lat") + "," + locJSON.getDouble("lng"));
						locs.add(locMap);
					} catch (JSONException e) {
						Log.w(LOG_TAG, "处理Google Place SearchAPI时发生JSON异常");
						Log.w(LOG_TAG, e);
					}
				}
				// 异步以后有可能活动不存在了
				if (null != getActivity()) {
					SimpleAdapter adapter = new SimpleAdapter(getActivity(), locs, R.layout.location_search_list_item,
							new String[] { "name" }, new int[] { R.id.location_name });
					mListView.setAdapter(adapter);
				}
			}
		}

		@Override
		protected List<JSONObject> doInBackground(String... params) {
			if (params == null || params.length == 0) {
				return null;
			}
			String location = params[0];
			if (StringUtils.isBlank(location)) {
				return null;
			}
			searchLocation = location;
			ArrayList<JSONObject> resultList = null;

			HttpURLConnection conn = null;
			StringBuilder jsonResults = new StringBuilder();
			try {
				StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_SEARCH + OUT_JSON);
				sb.append("?rankby=distance");
				sb.append("&key=" + API_KEY);
				sb.append("&keyword=" + URLEncoder.encode(location, "utf8"));
				sb.append("&sensor=true");
				String latlon = getLocation(getActivity());
				if (null == latlon) {
					latlon = "39.991,116.306";// 默认地址北大
				}
				Log.w(LOG_TAG, "find current location:" + latlon);
				sb.append("&location=" + latlon);
				URL url = new URL(sb.toString());
				Log.i(LOG_TAG, "send request to:" + url);
				conn = (HttpURLConnection) url.openConnection();
				InputStreamReader in = new InputStreamReader(conn.getInputStream());

				// Load the results into a StringBuilder
				int read;
				char[] buff = new char[1024];
				while ((read = in.read(buff)) != -1) {
					jsonResults.append(buff, 0, read);
				}
			} catch (MalformedURLException e) {
				Log.e(LOG_TAG, "Error processing Places API URL", e);
				return resultList;
			} catch (IOException e) {
				Log.e(LOG_TAG, "Error connecting to Places API", e);
				return resultList;
			} finally {
				if (conn != null) {
					conn.disconnect();
				}
			}

			try {
				// Create a JSON object hierarchy from the results
				JSONObject jsonObj = new JSONObject(jsonResults.toString());
				if ("OK".equals(jsonObj.getString("status"))) {
					JSONArray placesJsonArray = jsonObj.getJSONArray("results");

					// Extract the Place descriptions from the results
					resultList = new ArrayList<JSONObject>(placesJsonArray.length());
					for (int i = 0; i < placesJsonArray.length(); i++) {
						resultList.add(placesJsonArray.getJSONObject(i));
					}
				}

			} catch (JSONException e) {
				Log.e(LOG_TAG, "Cannot process JSON results", e);
			}

			return resultList;
		}
	}

	// Get the Location by GPS or WIFI
	public String getLocation(Context context) {
		return null == locationService ? null : locationService.getLatlng();
	}

}
